Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

swc/core panic using parse() and transform() APIs #9533

Open
TheLarkInn opened this issue Sep 5, 2024 · 4 comments
Open

swc/core panic using parse() and transform() APIs #9533

TheLarkInn opened this issue Sep 5, 2024 · 4 comments
Labels

Comments

@TheLarkInn
Copy link

Describe the bug

Error: failed to handle: index out of bounds: the len is 15 but the index is 18

Stack backtrace:
   0: <unknown>
   1: <unknown>
   2: <unknown>
   3: <unknown>
   4: <unknown>
   5: <unknown>
   6: _ZZN4node14ThreadPoolWork12ScheduleWorkEvENUlP9uv_work_sE_4_FUNES2_
   7: worker
             at /home/iojs/build/ws/out/../deps/uv/src/threadpool.c:122:5
   8: <unknown>
   9: <unknown>
Error: failed to handle: index out of bounds: the len is 15 but the index is 18

Stack backtrace:
   0: <unknown>
   1: <unknown>
   2: <unknown>
   3: <unknown>
   4: <unknown>
   5: <unknown>
   6: _ZZN4node14ThreadPoolWork12ScheduleWorkEvENUlP9uv_work_sE_4_FUNES2_
   7: worker
             at /home/iojs/build/ws/out/../deps/uv/src/threadpool.c:122:5
   8: <unknown>
   9: <unknown>
Error: failed to handle: index out of bounds: the len is 8 but the index is 9

Stack backtrace:
   0: <unknown>
   1: <unknown>
   2: <unknown>
   3: <unknown>
   4: <unknown>
   5: <unknown>
   6: _ZZN4node14ThreadPoolWork12ScheduleWorkEvENUlP9uv_work_sE_4_FUNES2_
   7: worker
             at /home/iojs/build/ws/out/../deps/uv/src/threadpool.c:122:5
   8: <unknown>
   9: <unknown>
Error: failed to handle: index out of bounds: the len is 8 but the index is 9

Stack backtrace:
   0: <unknown>
   1: <unknown>
   2: <unknown>
   3: <unknown>
   4: <unknown>
   5: <unknown>
   6: _ZZN4node14ThreadPoolWork12ScheduleWorkEvENUlP9uv_work_sE_4_FUNES2_
   7: worker
             at /home/iojs/build/ws/out/../deps/uv/src/threadpool.c:122:5
   8: <unknown>
   9: <unknown>

Input code

No response

Config

const options: Options = {
      cwd: buildFolderPath,
      root: srcDir,
      rootMode: 'root',
      configFile: false,
      swcrc: false,
      minify: false,

      inputSourceMap: false,
      sourceRoot,
      isModule: true,

      module: moduleConfig,
      jsc: {
        target,
        externalHelpers: tsconfig.options.importHelpers,
        parser: undefined,
        transform: {
          legacyDecorator: experimentalDecorators,
          react: {},
          useDefineForClassFields
        }
      }
    };

Playground link (or link to the minimal reproduction)

https://play.swc.rs/?version=1.7.23&code=H4sIAAAAAAAAA%2B2WW4vjNhSA3wP5D3rbp4kt323ahbZk3zoMzCwLW0pWko9jTRzJWHIu%2F76yk6UTHWhL6U4pHZOALH860rnqwKnXgyVCK2NJozX5nnxZLp5aaYj7PY9ulpGG7YDAie37DggHwUYDRFrSMkOUtq1UW2I1qTU5StsS2wLpO3beDnpUNWHuL514YPW8Ag4wnNGiYVRqmtqPnZXTPrYd3ApD9HAd9lp3K7JcLBe%2F8FF2dWUHpkwvO%2FiVPF2HTkJFgqMedqZnAkyga9PfHYFfBkLv91oFFjrYgx3OwZ4ptoUhMIMIHt3iDtYHUPZHZmBlzXJBCAkrMj3hKQ85ressjqFIyR35blQ7pY%2Fq%2FUxRj8pCkXNERb6skDcNomKfSmlDEZX4VAJCICpFsooUy8oQlfEcUTnaMU5KRBVIVpwkiCpvKJ41wLPYp7CfPw3Sfg0caXZ%2Fy9ed5NePzyZ4GOSBifNPHTNGNlIwK7V6OvewenbupyE6Zp0iw1DP%2BSllOUVupZFPNbxBKtNb53PORBOHiEo8qhRNCLfUt0kSqWo4XVODpv5ZeUZRCNLMP2tdCBQ2NMcaZdiGBbIOzVE409KXBXmOQjDyfFtnYQEosaNb33JRsgxqREWIqgXyWhT7VBmlgCjPtwKiIs0QlfoUYzjmosynwpDjc%2BU%2BVUCOdyzQjglH8Rt5ti%2BiJGUoJmLP9mUSxgnKq9izfZEXLnQQFSFZLMGUZ%2FuSJsCQ7WPP9kXSFHH%2BZ3n1jxelS5JNBejbJDFMd5wJfujlah7O%2BfwKev18mXwFzUzLPgCz4wCvpRuy6aso%2BSC7jg3XehxfawK5xjBPS5EzF72bz5%2FvE6VroMnT3Eo9uFbqk9ubRo%2BihXrsYHpbH9b3H7uHcjxspoNtzHqTbD58vF8%2FRptZfla9FE%2BzTKRiqqsTDcN8r%2F%2FRwywJWr2HQGpnsNk0wdFpPtpgtQpq6E0wHmYNXzR8oqKuuqbz%2Fi%2FrVFIkWeHqP6pAcXFL5bQuUlTz4rLyjxeePOpyCvLOTSm2h%2Fr9O9IzJcXOXQCTLqNxMaAF6wLBhq0OBthKMznr94tSDMyCWUl9lzU0r6PIXVk0DUPaBOYoNhc334WrOF%2Bl8zJzVpadNr02QXveSlCwGkwV52WVpNVyMUslzmJEN4RP7bWp5n67AzU17AXh7ts0cSHdVLlcGMvEjjhj7VwkCqje%2Btp%2Ft6%2F9L7eVb23fW9v3f2z73q7Xv369Om65%2BPIbQXnmoFsSAAA%3D&config=H4sIAAAAAAAAA1WPSw7DIAwF9zkF8rrbdtE79BAWdSIifrKJVBTl7iUE0maH3xsz8jooBbNoeKq1PMsQkYX4nEsi2Sf8lARIOxTNJia49XaWvRrRCtVoOxpIyBOluiX3hoMNQajjLXPGmzH%2FC3VwkUnkCu4o%2BsnSVTc0JbjwXmrZDkk50qF%2FwA%2FqsvNjMPLqm4kXGrYvhlQioBQBAAA%3D

SWC Info output

No response

Expected behavior

Error doesn't occur.

Actual behavior

Errors with obscure panic

Version

@swc/core: 1.7.23

Additional context

We are using the parse and transform API's async in a pseudo example seen below:

  const parsePromise: Promise<void> = Async.forEachAsync(
    sourceFilePaths,
    async (srcFilePath: string) => {
      const tsx: boolean = endsWithCharacterX(srcFilePath);
      const parserOptions: Buffer = tsx ? serializedTsxParserOptions : serializedNonTsxParserOptions;

      const start: number = performance.now();
      try {
        logger.terminal.writeDebugLine(`Parsing`, srcFilePath);
        const jsonAST: string = await parseFile(srcFilePath, parserOptions);
        serializedASTByFilePath.set(srcFilePath, jsonAST);
      } catch (error) {
        errors.push([srcFilePath, error as Error]);
        return;
      } finally {
        const end: number = performance.now();
        parseTimes.push([srcFilePath, end - start]);
      }
    },
    {
      concurrency: 4
    }
  );
  await Async.forEachAsync(
    outputs.iterateLeafNodes(),
    async (entry: [string, ITransformItem]) => {
      const { srcFilePath, relativeSrcFilePath, options, jsFilePath, mapFilePath } = entry[1];

      const jsonAST: string | undefined = serializedASTByFilePath.get(srcFilePath);
      if (!jsonAST) {
        errors.push([jsFilePath, new Error(`Missing AST for '${srcFilePath}'`)]);
        return;
      }

      let result: Output | undefined;

      const start: number = performance.now();
      try {
        logger.terminal.writeDebugLine(`Transpiling: ${srcFilePath}`);

        // TODO: Consider transformFile instead of parse + transform from bindings
        result = await transform(jsonAST, true, options);
      } catch (error) {
        errors.push([jsFilePath, error as Error]);
        return;
      } finally {
        const end: number = performance.now();
        transformTimes.push([jsFilePath, end - start]);
      }

      if (result) {
        let { code, map } = result;

        if (mapFilePath && map) {
          code += `\n//#sourceMappingUrl=./${basename(mapFilePath)}`;
          const parsedMap: ISourceMap = JSON.parse(map);
          parsedMap.sources[0] = relativeSrcFilePath;
          map = JSON.stringify(parsedMap);
          writeQueue.push([`${buildFolderPath}${mapFilePath}`, Buffer.from(map)]);
        }

        writeQueue.push([`${buildFolderPath}${jsFilePath}`, Buffer.from(code)]);
      }
    },
    {
      concurrency: 4
    }
  ).then(
    () => writeQueue.finish(),
    (error) => {
      writeQueue.finish();
      throw error;
    }
  );
@TheLarkInn
Copy link
Author

Is there any debug mode to show which file or call this panic'd on? Happy to provide more useful debugging information. Still trying to track down whether this is a file specific error.

@TheLarkInn
Copy link
Author

I used the playground on a file (thinking this was a file-specific/syntax problem) and then it worked successfully. So I saw there was an API (since we don't really need to parse, and we have the files) the transformFile() API instead, and this seemed to work.

So there is potentially something either with parse() or transform()

@dmichon-msft
Copy link

dmichon-msft commented Sep 5, 2024

This may also be a product of us using the underlying bindings directly to reduce duplicated serialization work. We had been using parseFile() + transform() instead of transformFile() to support passing the same AST to multiple different transforms, e.g. to emit both an ESM version and a CommonJS version of the same source module.

The behavior of our test rig should be analogous to calling transformFile where options.plugin = x => x.

@kdy1
Copy link
Member

kdy1 commented Oct 4, 2024

We had been using parseFile() + transform() instead of transformFile() to support passing the same AST to multiple different transforms

This is slower than using transformFile twice

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Development

No branches or pull requests

3 participants