227 |
current_class = CLASS_NONE; |
current_class = CLASS_NONE; |
228 |
|
|
229 |
/* tokenize the JavaScript */ |
/* tokenize the JavaScript */ |
230 |
JSTokenStream * token_stream = js_NewTokenStream(context, characters, num_characters, NULL, 1, NULL); |
JSTokenStream token_stream; |
231 |
if (token_stream == NULL) { |
if (! js_InitTokenStream(context, &token_stream, characters, num_characters, NULL, NULL, 1)) { |
232 |
fatal("cannot create token stream from JavaScript file %s", id); |
fatal("cannot create token stream from JavaScript file %s", id); |
233 |
} |
} |
234 |
|
|
|
/* see js_ParseTokenStream in jsparse.c */ |
|
|
JSObject * chain = NULL; |
|
|
JSContext * cx = context; |
|
|
JSStackFrame *fp, frame; |
|
|
|
|
|
/* |
|
|
* Push a compiler frame if we have no frames, or if the top frame is a |
|
|
* lightweight function activation, or if its scope chain doesn't match |
|
|
* the one passed to us. |
|
|
*/ |
|
|
fp = cx->fp; |
|
|
if (!fp || !fp->varobj || fp->scopeChain != chain) { |
|
|
memset(&frame, 0, sizeof frame); |
|
|
frame.varobj = frame.scopeChain = chain; |
|
|
if (cx->options & JSOPTION_VAROBJFIX) { |
|
|
while ((chain = JS_GetParent(cx, chain)) != NULL) |
|
|
frame.varobj = chain; |
|
|
} |
|
|
frame.down = fp; |
|
|
if (fp) |
|
|
frame.flags = fp->flags & (JSFRAME_SPECIAL | JSFRAME_COMPILE_N_GO); |
|
|
cx->fp = &frame; |
|
|
} |
|
|
|
|
|
/* |
|
|
* Protect atoms from being collected by a GC activation, which might |
|
|
* - nest on this thread due to out of memory (the so-called "last ditch" |
|
|
* GC attempted within js_NewGCThing), or |
|
|
* - run for any reason on another thread if this thread is suspended on |
|
|
* an object lock before it finishes generating bytecode into a script |
|
|
* protected from the GC by a root or a stack frame reference. |
|
|
*/ |
|
|
JS_KEEP_ATOMS(cx->runtime); |
|
|
|
|
235 |
for (;;) { |
for (;;) { |
236 |
JSTokenType tt = js_GetToken(context, token_stream); |
JSTokenType tt = js_GetToken(context, &token_stream); |
237 |
|
|
238 |
if (tt == TOK_ERROR) { |
if (tt == TOK_ERROR) { |
239 |
fatal("JavaScript parse error: %s: line = %d, col = %d\n", id, line_num, column_num); |
fatal("JavaScript parse error: %s: line = %d, col = %d\n", id, line_num, column_num); |
245 |
} |
} |
246 |
|
|
247 |
/* mark the chars before the token */ |
/* mark the chars before the token */ |
248 |
JSToken t = CURRENT_TOKEN(token_stream); |
JSToken t = CURRENT_TOKEN(&token_stream); |
249 |
mark_nontoken_chars(t.pos.begin.lineno, t.pos.begin.index); |
mark_nontoken_chars(t.pos.begin.lineno, t.pos.begin.index); |
250 |
|
|
251 |
/* mark the token */ |
/* mark the token */ |
256 |
abort(); |
abort(); |
257 |
case TOK_EOL: |
case TOK_EOL: |
258 |
class = CLASS_NONE; |
class = CLASS_NONE; |
259 |
token_stream->flags |= TSF_OPERAND; |
token_stream.flags |= TSF_OPERAND; |
260 |
break; |
break; |
261 |
case TOK_SEMI: |
case TOK_SEMI: |
262 |
case TOK_COMMA: |
case TOK_COMMA: |
276 |
case TOK_STAR: |
case TOK_STAR: |
277 |
case TOK_DIVOP: |
case TOK_DIVOP: |
278 |
class = CLASS_SYMBOL; |
class = CLASS_SYMBOL; |
279 |
token_stream->flags |= TSF_OPERAND; |
token_stream.flags |= TSF_OPERAND; |
280 |
break; |
break; |
281 |
case TOK_UNARYOP: |
case TOK_UNARYOP: |
282 |
switch (t.t_op) { |
switch (t.t_op) { |
285 |
case JSOP_NOT: |
case JSOP_NOT: |
286 |
case JSOP_BITNOT: |
case JSOP_BITNOT: |
287 |
class = CLASS_SYMBOL; |
class = CLASS_SYMBOL; |
288 |
token_stream->flags |= TSF_OPERAND; |
token_stream.flags |= TSF_OPERAND; |
289 |
break; |
break; |
290 |
case JSOP_TYPEOF: |
case JSOP_TYPEOF: |
291 |
class = CLASS_KEYWORD; |
class = CLASS_KEYWORD; |
292 |
token_stream->flags |= TSF_OPERAND; |
token_stream.flags |= TSF_OPERAND; |
293 |
break; |
break; |
294 |
case JSOP_VOID: |
case JSOP_VOID: |
295 |
class = CLASS_TYPE; |
class = CLASS_TYPE; |
296 |
token_stream->flags |= TSF_OPERAND; |
token_stream.flags |= TSF_OPERAND; |
297 |
break; |
break; |
298 |
default: |
default: |
299 |
abort(); |
abort(); |
302 |
case TOK_INC: |
case TOK_INC: |
303 |
case TOK_DEC: |
case TOK_DEC: |
304 |
class = CLASS_SYMBOL; |
class = CLASS_SYMBOL; |
305 |
/* token_stream->flags does not change w.r.t. TSF_OPERAND */ |
/* token_stream.flags does not change w.r.t. TSF_OPERAND */ |
306 |
break; |
break; |
307 |
case TOK_DOT: |
case TOK_DOT: |
308 |
case TOK_LB: |
case TOK_LB: |
309 |
class = CLASS_SYMBOL; |
class = CLASS_SYMBOL; |
310 |
token_stream->flags |= TSF_OPERAND; |
token_stream.flags |= TSF_OPERAND; |
311 |
break; |
break; |
312 |
case TOK_RB: |
case TOK_RB: |
313 |
class = CLASS_SYMBOL; |
class = CLASS_SYMBOL; |
314 |
token_stream->flags &= ~TSF_OPERAND; |
token_stream.flags &= ~TSF_OPERAND; |
315 |
break; |
break; |
316 |
case TOK_LC: |
case TOK_LC: |
317 |
class = CLASS_CBRACKET; |
class = CLASS_CBRACKET; |
318 |
token_stream->flags |= TSF_OPERAND; |
token_stream.flags |= TSF_OPERAND; |
319 |
break; |
break; |
320 |
case TOK_RC: |
case TOK_RC: |
321 |
class = CLASS_CBRACKET; |
class = CLASS_CBRACKET; |
322 |
token_stream->flags &= ~TSF_OPERAND; |
token_stream.flags &= ~TSF_OPERAND; |
323 |
break; |
break; |
324 |
case TOK_LP: |
case TOK_LP: |
325 |
class = CLASS_SYMBOL; |
class = CLASS_SYMBOL; |
326 |
token_stream->flags |= TSF_OPERAND; |
token_stream.flags |= TSF_OPERAND; |
327 |
break; |
break; |
328 |
case TOK_RP: |
case TOK_RP: |
329 |
class = CLASS_SYMBOL; |
class = CLASS_SYMBOL; |
330 |
token_stream->flags &= ~TSF_OPERAND; |
token_stream.flags &= ~TSF_OPERAND; |
331 |
break; |
break; |
332 |
case TOK_NAME: |
case TOK_NAME: |
333 |
class = CLASS_NONE; |
class = CLASS_NONE; |
334 |
token_stream->flags &= ~TSF_OPERAND; |
token_stream.flags &= ~TSF_OPERAND; |
335 |
if (js_PeekToken(context, token_stream) == TOK_LP) { |
if (js_PeekToken(context, &token_stream) == TOK_LP) { |
336 |
/* function */ |
/* function */ |
337 |
class = CLASS_NONE; |
class = CLASS_NONE; |
338 |
} |
} |
339 |
break; |
break; |
340 |
case TOK_NUMBER: |
case TOK_NUMBER: |
341 |
class = CLASS_NUMBER; |
class = CLASS_NUMBER; |
342 |
token_stream->flags &= ~TSF_OPERAND; |
token_stream.flags &= ~TSF_OPERAND; |
343 |
break; |
break; |
344 |
case TOK_STRING: |
case TOK_STRING: |
345 |
class = CLASS_STRING; |
class = CLASS_STRING; |
346 |
token_stream->flags &= ~TSF_OPERAND; |
token_stream.flags &= ~TSF_OPERAND; |
347 |
break; |
break; |
348 |
case TOK_OBJECT: |
case TOK_REGEXP: |
349 |
class = CLASS_REGEXP; |
class = CLASS_REGEXP; |
350 |
token_stream->flags &= ~TSF_OPERAND; |
token_stream.flags &= ~TSF_OPERAND; |
351 |
break; |
break; |
352 |
case TOK_PRIMARY: |
case TOK_PRIMARY: |
353 |
switch (t.t_op) { |
switch (t.t_op) { |
356 |
case JSOP_NULL: |
case JSOP_NULL: |
357 |
case JSOP_THIS: |
case JSOP_THIS: |
358 |
class = CLASS_KEYWORD; |
class = CLASS_KEYWORD; |
359 |
token_stream->flags &= ~TSF_OPERAND; |
token_stream.flags &= ~TSF_OPERAND; |
360 |
break; |
break; |
361 |
default: |
default: |
362 |
abort(); |
abort(); |
364 |
break; |
break; |
365 |
case TOK_FUNCTION: |
case TOK_FUNCTION: |
366 |
class = CLASS_KEYWORD; |
class = CLASS_KEYWORD; |
367 |
token_stream->flags |= TSF_OPERAND; |
token_stream.flags |= TSF_OPERAND; |
|
break; |
|
|
case TOK_EXPORT: |
|
|
case TOK_IMPORT: |
|
|
abort(); |
|
368 |
break; |
break; |
369 |
case TOK_IF: |
case TOK_IF: |
370 |
case TOK_ELSE: |
case TOK_ELSE: |
382 |
case TOK_RETURN: |
case TOK_RETURN: |
383 |
case TOK_NEW: |
case TOK_NEW: |
384 |
case TOK_DELETE: |
case TOK_DELETE: |
385 |
token_stream->flags |= TSF_OPERAND; |
token_stream.flags |= TSF_OPERAND; |
386 |
class = CLASS_KEYWORD; |
class = CLASS_KEYWORD; |
387 |
break; |
break; |
388 |
case TOK_DEFSHARP: |
case TOK_DEFSHARP: |
395 |
case TOK_THROW: |
case TOK_THROW: |
396 |
case TOK_INSTANCEOF: |
case TOK_INSTANCEOF: |
397 |
case TOK_DEBUGGER: |
case TOK_DEBUGGER: |
398 |
token_stream->flags |= TSF_OPERAND; |
token_stream.flags |= TSF_OPERAND; |
399 |
class = CLASS_KEYWORD; |
class = CLASS_KEYWORD; |
400 |
break; |
break; |
401 |
case TOK_XMLSTAGO: |
case TOK_XMLSTAGO: |
457 |
output_character('\n', CLASS_NONE); |
output_character('\n', CLASS_NONE); |
458 |
} |
} |
459 |
|
|
460 |
/* cleanup */ |
js_CloseTokenStream(context, &token_stream); |
|
JS_UNKEEP_ATOMS(cx->runtime); |
|
|
context->fp = fp; |
|
461 |
} |
} |